<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="zh" xml:lang="zh" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<head>
<META http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Guideline: 测试设计</title>
<meta name="uma.type" content="Guideline">
<meta name="uma.name" content="test_design">
<meta name="uma.presentationName" content="测试设计">
<meta name="element_type" content="other">
<meta name="filetype" content="description">
<meta name="role" content="">
<link rel="StyleSheet" href="./../../../css/default.css" type="text/css">
<script src="./../../../scripts/ContentPageResource.js" type="text/javascript" language="JavaScript"></script><script src="./../../../scripts/ContentPageSection.js" type="text/javascript" language="JavaScript"></script><script src="./../../../scripts/ContentPageSubSection.js" type="text/javascript" language="JavaScript"></script><script src="./../../../scripts/ContentPageToolbar.js" type="text/javascript" language="JavaScript"></script><script src="./../../../scripts/contentPage.js" type="text/javascript" language="JavaScript"></script><script type="text/javascript" language="JavaScript">
					var backPath = './../../../';
					var imgPath = './../../../images/';
					var nodeInfo=null;
					contentPage.preload(imgPath, backPath, nodeInfo,  '', false, false, false);
				</script>
</head>
<body>
<div id="breadcrumbs"></div>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td valign="top"><a name="Top"></a>
<div id="page-guid" value="7.713819799229519E-305"></div>
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td class="pageTitle" nowrap="true">Guideline: 测试设计</td><td width="100%">
<div align="right" id="contentPageToolbar"></div>
</td><td width="100%" class="expandCollapseLink" align="right"><a name="mainIndex" href="./../../../index.htm"></a><script language="JavaScript" type="text/javascript" src="./../../../scripts/treebrowser.js"></script></td>
</tr>
</table>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td class="pageTitleSeparator"><img src="./../../../images/shim.gif" alt="" title="" height="1"></td>
</tr>
</table>
<div class="overview">
<table width="97%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td width="50"><img src="./../../../images/guidance.gif" alt="" title=""></td><td>
<table class="overviewTable" border="0" cellspacing="0" cellpadding="0">
<tr>
<td valign="top">本指南说明如何确定和设计测试。</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
<div class="sectionHeading">Relationships</div>
<div class="sectionContent">
<table class="sectionTable" border="0" cellspacing="0" cellpadding="0">
<tr valign="top">
<th class="sectionTableHeading" scope="row">Related Elements</th><td class="sectionTableCell">
<ul>
<li>
<a href="./../../../rup/domains/test_FBB424F8.html" guid="_SPvXcN7IEdm8G6yT7-Wdqw">测试</a>
</li>
<li>
<a href="./../../../rup/workproducts/rup_test_design_DD152CC4.html" guid="{1EDAA1F0-EB1D-4175-A59A-2ED82642F89B}">测试设计</a>
</li>
<li>
<a href="./../../../rup/roles/rup_test_designer_5F59E64F.html" guid="{84F723B5-288F-4AC4-B6C1-C75A07BFEEED}">测试设计人员</a>
</li>
</ul>
</td>
</tr>
</table>
</div>
<div class="sectionHeading">Main Description</div>
<div class="sectionContent">
<table class="sectionTable" border="0" cellspacing="0" cellpadding="0">
<tr valign="top">
<td class="sectionTableSingleCell"><a id="Top" name="Top"></a><a key="测试设计（test design）" text="指南" name="XE_test_design__guidelines_for" id="XE_test_design__guidelines_for" class="index"></a> 
<h3>
    <a id="Explanation" name="Explanation">说明</a>
</h3>
<p>
    清楚了解用户期望值（这样就可以验证和确认这些期望值），对用户对于软件的满意程度的影响是最大的。
    测试用例反映了要验证的需求。但可由不同的测试人员以不同方式来验证这些需求。例如，可由某个测试人员使用自动测试技术来执行软件以验证其功能和性能，可通过手工测试和观察来执行计算机系统的关机顺序，而市场份额和销售额（以及产品需求）将通过评估产品和竞争性销售来实现。
</p>
<p>
    由于您可能无法（或不负责）验证所有需求，选择最适合或最关键的测试需求对于您的项目取得成功至关重要。选定要验证的需求将在成本、风险和验证需求的必要性之间达成平衡。
</p>
<p>
    确定测试用例是很重要的，这有几个理由。
</p>
<ul>
    <li>
        测试用例形成了设计和制定“测试脚本”的基础。
    </li>
    <li>
        测试的“深度”与测试用例的数目是成比例的。由于每个测试用例都反映了不同的场景、条件或产品流程，所以当测试用例的数目增加时，产品和测试流程的质量的可信度就得到提高。
    </li>
    <li>
        测试完整性的主要度量标准是基于需求的覆盖范围，这是以确定的、实现的和／或执行的测试用例的数目为基础的。诸如“已执行并验证了 95% 的关键测试用例”之类的声明比声称“我们已完成测试工作的 95%”更有意义。
    </li>
    <li>
        测试工作的规模是与测试用例的数目成比例的。通过对测试用例进行全面地分类，可以更精确地估计测试周期后续阶段的计时。
    </li>
    <li>
        测试设计和开发的种类以及所需的资源在很大程度上受测试用例的支配。
    </li>
</ul>
<p>
    测试用例通常是根据测试类型或相关测试的需求进行分类或归类的，分类结果也将相应变化。实践至少要为每个测试需求开发两个测试用例：
</p>
<ul>
    <li>
        一个测试用例将证明需求已实现。这称为正测试用例。
    </li>
    <li>
        另一个测试用例，反映无法接受的、异常的或意外的条件或数据，用来证明仅在所需的条件下才可实现需求，这被称为负测试用例。
    </li>
</ul>
<h3>
    <a id="DerivingTestCasesforUnitTest" name="DerivingTestCasesforUnitTest">得出针对单元测试的测试用例</a>
</h3>
<p>
    单元测试要求测试单元的内部结构及其行为特征。测试内部结构需要了解是如何实现单元的，基于这种了解的测试被称为白匣测试。对单元的行为特征进行测试时着重于单元的外部可观测行为，而无需了解或注意单元的实现。基于该方法的测试被称为黑匣测试。下面将描述基于这两种方法而得出的测试用例。
</p>
<h4>
    <a id="WhiteBox_tests" name="WhiteBox_tests"></a><a key="白匣测试（white-box test）" text="单元的白匣测试" name="XE_white-box_test__of_units" id="XE_white-box_test__of_units" class="index"></a>
</h4>
<p>
    从理论上讲，应测试代码中每个可能的路径。在所有非常简单的单元中实现这样的目标是不切实际的，或几乎是不可能的。无论如何，您至少应将每个<b>决策到决策的路径</b>（DD 路径）应用一次，从而至少将所有语句执行一次。决策一般为 if
    语句，DD 路径是指两个决策之间的路径。
</p>
<p>
    要实现这种程度的测试覆盖，建议您选择测试数据，这样就可按照每种可能的方法来评估每个决策。评估结束后，测试用例应确保：
</p>
<ul>
    <li>
        得出每个布尔表达式的 <b>true</b> 和 <b>false</b> 值。例如，表达式 (a&lt;3) OR (b&gt;4) 的结果为 <b>true</b>/<b>false</b> 的四种组合。
    </li>
    <li>
        每个无限循环至少执行零次、一个或多于一次。
    </li>
</ul>
<p>
    使用代码覆盖工具确定白匣测试未曾执行的代码。可靠性测试应与白匣测试同时进行。
</p>
<p class="exampleheading">
    示例：
</p>
<p class="example">
    假设在类 <b>Set of Integers</b> 中，对函数 <b>member</b> 执行结构测试。在二进制搜索的帮助下，测试会检查该集合是否包含某个给定的整数。
</p>
<p class="picturecenter" align="center">
    <img height="200" alt="在图表说明中描述的图。" src="./../../../rup/guidances/guidelines/resources/untst001.gif" width="301" />
</p>
<p class="picturetext">
    member 函数及其对应的流程图。虚线箭头说明了如何使用两个测试用例将所有的语句至少执行一次。
</p>
<p>
    从理论上讲，对于一个要进行彻底测试的操作，测试用例应遍历代码中各路线的所有组合。在 <b>member</b> 中，<b>while
    循环</b>内存在三条备用路线。测试用例可数次遍历或根本不遍历该循环。如果测试用例根本不遍历该循环，您将只能发现通过该代码的一条路线。如果用例遍历该循环一次，将发现三条路线。如果遍历两次，将发现六条路线，依此类推。因此，路线的总数将是
    1+3+6+12+24+48+...，这实际上是路线组合的一个无法控制的数目。这就是您为什么必须选择所有这些路线的一小部分的原因。在本示例中，您可以使用两个测试用例来执行所有语句。在一个测试用例中，您可能选择 <code><b>Set
    of Integers</b> = {1,5,7,8,11}</code> 以及 <code><b>t</b> = 3</code> 作为测试数据。在其他测试用例中，您可能选择 <code><b>Set of Integers</b> =
    {1,5,7,8,11}</code> 以及 <code><b>t</b> = 8</code>。
</p>
<p>
    关于其他信息，请参阅<a class="elementLinkWithType" href="./../../../rup/guidances/guidelines/unit_test_9A3F053.html" guid="9.315724622037552E-305">Guideline: 单元测试</a>。
</p>
<h4>
    <a id="BlackBox_Tests" name="BlackBox_Tests"></a>黑匣测试<a key="黑匣测试（black-box test）" text="单元的黑匣测试" name="XE_black-box_test__of_units" id="XE_black-box_test__of_units" class="index"></a>
</h4>
<p>
    黑匣测试的目的是验证单元的指定行为，而无需了解单元<b>如何</b>实现该行为。黑匣测试着重并依赖于单元的输入和输出信息。
</p>
<p>
    <b>等价划分</b>是一项减少所需的测试数目的技术。对于每个操作，您应确定实参和对象状态的等价类。<b>等价类</b>是一组值，假设某一对象对这些值表现类似的行为。例如，一个 <b>Set</b>
    有三个等价类：<b>空</b>、<b>某些元素</b>和<b>满</b>。
</p>
<p>
    使用代码覆盖工具确定白匣测试未曾执行的代码。可靠性测试应与黑匣测试同时进行。
</p>
<p>
    以下两个子节描述如何通过为特定实参选择测试数据来确定测试用例。
</p>
<h5>
    基于输入实参的测试用例
</h5>
<p>
    <b>输入实参</b>是由某个操作使用的实参。应通过针对每个操作及以下的每个输入条件使用输入实参，来创建测试用例：
</p>
<ul>
    <li>
        每个等价类的正常值。
    </li>
    <li>
        每个等价类的边界值。
    </li>
    <li>
        等价类之外的值。
    </li>
    <li>
        非法值。
    </li>
</ul>
<p>
    记住，要将对象状态看作输入实参。例如，如果要对对象 <b>Set</b> 测试 <b>add</b> 操作，则必须使用 <b>Set</b> 的等价类的所有值来测试 <b>add</b>，使用满的
    <b>Set</b>、<b>Set</b> 中的某些元素以及空 <b>Set</b>。
</p>
<h5>
    基于输出实参的测试用例
</h5>
<p>
    <b>输出实参</b>是操作所更改的实参。实参可以既是输入实参又是输出实参。选择输入，您将根据以下的每种条件得到<b>输出</b>。
</p>
<ul>
    <li>
        每个等价类的正常值。
    </li>
    <li>
        每个等价类的边界值。
    </li>
    <li>
        等价类之外的值。
    </li>
    <li>
        非法值。
    </li>
</ul>
<p>
    记住，要将对象状态看作输出实参。如果（举例）测试 <b>List</b> 的 <b>remove</b> 操作，则必须选择输入值，这样，在执行操作后，<b>List</b> 即填满、有某些元素或为空（使用其所有等价类的值进行测试）。
</p>
<p>
    如果对象受状态的控制（根据对象的状态产生不同的反应），则应使用如下图中所示的那种状态矩阵。
</p>
<p class="picturecenter" align="center">
    <img height="166" alt="在图表说明中描述的图。" src="./../../../rup/guidances/guidelines/resources/untst002.gif" width="184" />
</p>
<p class="picturetext">
    用于测试的状态矩阵。可基于该矩阵来测试状态和激励的所有组合。
</p>
<p>
    关于其他信息，请参阅<a class="elementLinkWithType" href="./../../../rup/guidances/guidelines/unit_test_9A3F053.html" guid="9.315724622037552E-305">Guideline: 单元测试</a>。
</p><br />
<br /></td>
</tr>
</table>
</div>
<table class="copyright" border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="copyright">Copyright &copy; 2008 版权所有 东软集团股份有限公司&nbsp; 联系邮箱:<a href="mailto:tcoe@neusoft.com">tcoe@neusoft.com</a></td>
</tr>
</table>
</td>
</tr>
</table>
</body>
<script type="text/javascript" language="JavaScript">
				contentPage.onload();
			</script>
</html>
